package com.dupt.system.service.impl;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;

import com.alibaba.fastjson2.JSON;
import com.dupt.common.config.DUPTConfig;
import com.dupt.common.utils.StringUtils;
import com.dupt.common.utils.file.FileUploadUtils;
import com.dupt.common.utils.file.FileUtils;
import com.dupt.system.domain.MaterialDetial;
import com.dupt.system.domain.vo.MaterialDetialVo;
import com.dupt.system.mapper.*;
import com.dupt.system.service.IMaterialDetialService;
import com.dupt.common.utils.DateUtils;
import com.dupt.common.utils.SecurityUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

/**
 * 物料明细Service业务层处理
 * 
 * @author zhuanyusun
 * @date 2025-06-09
 */
@Service
public class MaterialDetialServiceImpl implements IMaterialDetialService
{
    @Autowired
    private MaterialDetialMapper materialDetialMapper;

    /**
     * 查询物料明细
     * 
     * @param materialDetialId 物料明细主键
     * @return 物料明细
     */
    @Override
    public MaterialDetialVo selectMaterialDetialByMaterialDetialId(Long materialDetialId)
    {
        MaterialDetialVo materialDetialVo = new MaterialDetialVo();
        try {
            MaterialDetial detial = materialDetialMapper.selectMaterialDetialByMaterialDetialId(materialDetialId);
            BeanUtils.copyProperties(detial, materialDetialVo);
            List<String> fileNames = new ArrayList<>();
            if(!StringUtils.isEmpty(detial.getFilePath())){
                //读取指定路径的所有文件
                String filePath = DUPTConfig.getUploadPath() + detial.getFilePath();
                Path startPath = Paths.get(filePath);
                if(Files.exists(startPath)){
                    //递归遍历所有文件
                    Files.walk(startPath)
                            .filter(Files::isRegularFile)
                            .map(startPath::relativize)  // 获取相对路径
                            .map(Path::toString)
                            .forEach(fileNames::add);
                    materialDetialVo.setFileNameList(fileNames);
                }
            }
        }catch (Exception e){
            throw new RuntimeException("递归遍历目录失败 ", e);
        }
        return materialDetialVo;
    }

    /**
     * 批量查询物料明细
     *
     * @param materialDetialIds 物料明细主键
     * @return 物料明细
     */
//    @Override
//    public List<MaterialDetial> selectMaterialDetialByMaterialDetialIds(Long[] materialDetialIds)
//    {
//        return materialDetialMapper.selectMaterialDetialByMaterialDetialIds(materialDetialIds);
//    }

    /**
     * 钉钉查询物料明细列表
     *
     * @param materialDetial 物料明细
     * @return 物料明细
     */
    @Override
    public List<MaterialDetial> selectMaterialDetialListOfDingTalk(MaterialDetial materialDetial)
    {
        List<MaterialDetial> detialList = materialDetialMapper.selectMaterialDetialList(materialDetial);
//        detialList.forEach(detial -> {
//            detial.setStatus(DictUtils.getDictLabel("sys_material_status",detial.getStatus()));
//            detial.setApplicableTemp(DictUtils.getDictLabel("sys_applicable_temp",detial.getApplicableTemp()));
//        });
        return detialList;
    }

    /**
     * 查询物料明细列表
     * 
     * @param materialDetial 物料明细
     * @return 物料明细
     */
    @Override
    public List<MaterialDetialVo> selectMaterialDetialList(MaterialDetial materialDetial)
    {
        List<MaterialDetial> materialDetialList = materialDetialMapper.selectMaterialDetialList(materialDetial);
        List<MaterialDetialVo> materialDetialVoList = JSON.parseArray(JSON.toJSONString(materialDetialList), MaterialDetialVo.class);
        for(MaterialDetialVo materialDetialVo : materialDetialVoList){
            List<String> fileNames = new ArrayList<>();
            try {
                if(!StringUtils.isEmpty(materialDetialVo.getFilePath())){
                    //读取指定路径的所有文件
                    String filePath = DUPTConfig.getUploadPath() + materialDetialVo.getFilePath();
                    Path startPath = Paths.get(filePath);
                    if(Files.exists(startPath)){
                        //递归遍历所有文件
                        Files.walk(startPath)
                                .filter(Files::isRegularFile)
                                .map(startPath::relativize)  // 获取相对路径
                                .map(Path::toString)
                                .forEach(fileNames::add);
                        materialDetialVo.setFileNameList(fileNames);
                    }
                }
            } catch (IOException e) {
                throw new RuntimeException("递归遍历目录失败 ", e);
            }
        }
        return materialDetialVoList;
    }


    /**
     * 新增物料明细
     *
     * @param materialDetialVo 物料明细
     * @Param files 文件
     * * @return 结果
     */
    public int insertMaterialDetial(String materialDetialVo, List<MultipartFile> files) throws IOException{

        //1.保存质量追溯信息
        MaterialDetial detial = JSON.parseObject(materialDetialVo,MaterialDetial.class);

        //2.处理物料内码
        //2.1 如果存在物料内码，则直接使用，同时检查物料编码（ERP），如果存在物料编码，则直接使用，如果不存在物料编码，则根据物料内码获取物料编码
        if(StringUtils.isNotEmpty(detial.getMaterialInnerCode()) ){
            //如果物料编码（ERP）为空，则根据物料内码获取物料编码
            if(StringUtils.isEmpty(detial.getMaterialCode()))
            {
                List<MaterialDetial> detialList = materialDetialMapper.selectMaterialDetialByMaterialInnerCode(detial.getMaterialInnerCode());
                if(detialList.size()>0){
                    detial.setMaterialCode(detialList.get(0).getMaterialCode());
                }
            }
        }
        //2.2 如果不存在物料内码
        else if(StringUtils.isEmpty(detial.getMaterialInnerCode()))
        {
            //如果物料编码（ERP）不为空，则根据物料编码（ERP）获取物料内码
            if(StringUtils.isNotEmpty(detial.getMaterialCode()))
            {
                List<MaterialDetial> detialList = materialDetialMapper.selectMaterialDetialByMaterialCode(detial.getMaterialCode());
                if(detialList.size()>0){
                    detial.setMaterialInnerCode(detialList.get(0).getMaterialInnerCode());
                }else
                {
                    String currentTime = DateUtils.dateTime(new Date());
                    List<MaterialDetial> detials = materialDetialMapper.selectMaterialDetialByMaterialInnerCode(currentTime);
                    detial.setMaterialInnerCode("DT"+currentTime+String.format("%03d", detials.stream().count()==0?1:detials.size()+1));
                }
            }
            //如果物料编码（ERP）为空，则根据名称、规格型号获取物料内码
            else{
                List<MaterialDetial> detialList = materialDetialMapper.selectMaterialDetialByMaterialNameAndMaterialItem(detial.getMaterialName(), detial.getMaterialItem());
                if(detialList.size()>0){
                    detial.setMaterialInnerCode(detialList.get(0).getMaterialInnerCode());
                    detial.setMaterialCode(detialList.get(0).getMaterialCode());
                }
                else {
                    String currentTime = DateUtils.dateTime(new Date());
                    List<MaterialDetial> detials = materialDetialMapper.selectMaterialDetialByMaterialInnerCode(currentTime);
                    detial.setMaterialInnerCode("DT"+currentTime+String.format("%03d", detials.stream().count()==0?1:detials.size()+1));
                }
            }
        }
        //3.根据是否设置序列号，判断是否保存相应序列号
        if(detial.getIsSetSerial() == "0")
            detial.setSerialNo(null);

        //4.保存文件到服务器
        // 上传文件路径
        String filePath = DUPTConfig.getUploadPath();
        if(files!=null){
            for (MultipartFile file : files) {
                // 上传并返回新文件名称
                String fileName = FileUploadUtils.upload(filePath, file);
                // 确保数据库存储的是相对路径（不带profile/upload）
                if (fileName.startsWith("/profile/upload/")) {
                    // 找到最后一个斜杠的位置
                    int lastSlashIndex = fileName.lastIndexOf('/');
                    // 找到倒数第二个斜杠的位置
                    int secondLastSlashIndex = fileName.lastIndexOf('/', lastSlashIndex - 1);
                    // 截取两个斜杠之间的内容（包含斜杠）
                    fileName = fileName.substring(secondLastSlashIndex, lastSlashIndex + 1);
                }
                detial.setFilePath(fileName);
            }
        }
        detial.setCurrentPos(detial.getSavePos());
        detial.setCreateTime(DateUtils.getNowDate());
        detial.setCreateBy(SecurityUtils.getLoginUser().getUsername());
        return materialDetialMapper.insertMaterialDetial(detial);
    }

    /**
     * 修改物料明细
     * 
     * @param materialDetialVo 物料明细
     * @return 结果
     */
    @Override
    public int updateMaterialDetial(String materialDetialVo, List<MultipartFile> files) throws IOException {
        {
            //1.保存质量追溯信息
            MaterialDetialVo detialVo = JSON.parseObject(materialDetialVo, MaterialDetialVo.class);
            MaterialDetial detial = materialDetialMapper.selectMaterialDetialByMaterialDetialId(detialVo.getMaterialDetialId());
            detial.setMaterialCode(detialVo.getMaterialCode());
            detial.setMaterialName(detialVo.getMaterialName());
            detial.setMaterialItem(detialVo.getMaterialItem());
            detial.setMaterialPrecision(detialVo.getMaterialPrecision());
            detial.setTexture(detialVo.getTexture());
            detial.setUnit(detialVo.getUnit());
            detial.setIsSetSerial(detialVo.getIsSetSerial());
            detial.setSerialNo(detialVo.getSerialNo());
            detial.setBatchNo(detialVo.getBatchNo());
            detial.setApplicableTemp(detialVo.getApplicableTemp());
            detial.setSavePos(detialVo.getSavePos());
            detial.setCurrentPos(detialVo.getSavePos());
            detial.setManufacturer(detialVo.getManufacturer());
            detial.setManufactureNo(detialVo.getManufactureNo());
            detial.setPurchaseAmount(detialVo.getPurchaseAmount());
            detial.setPurchaseCycle(detialVo.getPurchaseCycle());
            detial.setRemark(detialVo.getRemark());
            // 上传文件路径
            String filePath = DUPTConfig.getUploadPath();
            //2.查询原有的所有文件，根据传来的文件作对比，删除不存在的文件
            List<String> fileNames = new ArrayList<>();
            try {
                if (!StringUtils.isEmpty(detial.getFilePath())) {
                    //读取指定路径的所有文件
                    Path startPath = Paths.get(filePath + detial.getFilePath());
                    if (Files.notExists(startPath)) {
                        Files.createDirectory(startPath);
                    }
                    //递归遍历所有文件
                    Files.walk(startPath)
                            .filter(Files::isRegularFile)
                            .map(startPath::relativize)  // 获取相对路径
                            .map(Path::toString)
                            .forEach(fileNames::add);
                }
            } catch (IOException e) {
                throw new RuntimeException("递归遍历目录失败 ", e);
            }
            for (String fileName : fileNames) {
                if (!detialVo.getFileNameList().contains(fileName)) {
                    FileUtils.deleteFile(filePath + detial.getFilePath() + fileName);
                }
            }

            //3.保存文件到服务器指定的文件夹中
            for (MultipartFile file : files) {
                if (StringUtils.isNotEmpty(detial.getFilePath())) {
                    FileUtils.uploadFile(file, filePath + detial.getFilePath());
                } else {
                    //String originalFilename = file.getOriginalFilename();
                    // 上传并返回新文件名称
                    String fileName = FileUploadUtils.upload(filePath, file);
                    // 确保数据库存储的是相对路径（不带profile/upload）
                    if (fileName.startsWith("/profile/upload/")) {
                        // 找到最后一个斜杠的位置
                        int lastSlashIndex = fileName.lastIndexOf('/');
                        // 找到倒数第二个斜杠的位置
                        int secondLastSlashIndex = fileName.lastIndexOf('/', lastSlashIndex - 1);

                        // 截取两个斜杠之间的内容（包含斜杠）
                        fileName = fileName.substring(secondLastSlashIndex, lastSlashIndex + 1);
                    }
                    detialVo.setFilePath(fileName);
                }
            }
            detial.setUpdateBy(SecurityUtils.getLoginUser().getUsername());
            detial.setUpdateTime(DateUtils.getNowDate());
            return materialDetialMapper.updateMaterialDetial(detial);
        }
    }

    /**
     * 批量删除物料明细
     *
     * @param materialDetialIds 需要删除的物料明细主键
     * @return 结果
     */
    @Override
    public int deleteMaterialDetialByMaterialDetialIds(Long[] materialDetialIds)
    {
        return materialDetialMapper.deleteMaterialDetialByMaterialDetialIds(materialDetialIds);
    }
}
